#ifndef JOYSTICKREADER_H
#define JOYSTICKREADER_H

#include <QObject>
#include <hidapi/hidapi.h>
#include <QThread>

class JoystickReader : public QObject {
    Q_OBJECT

    // 摇杆
    Q_PROPERTY(ButtonState button1 READ button1 WRITE setButton1 NOTIFY button1Changed FINAL)
    Q_PROPERTY(ButtonState button2 READ button2 WRITE setButton2 NOTIFY button2Changed FINAL)
    Q_PROPERTY(ButtonState button3 READ button3 WRITE setButton3 NOTIFY button3Changed FINAL)
    Q_PROPERTY(TriggerState trigger1 READ trigger1 WRITE setTrigger1 NOTIFY trigger1Changed FINAL)
    Q_PROPERTY(TriggerState trigger2 READ trigger2 WRITE setTrigger2 NOTIFY trigger2Changed FINAL)
    Q_PROPERTY(AxisState axis4 READ axis4 WRITE setAxis4 NOTIFY axis4Changed FINAL)
    Q_PROPERTY(AxisState axis5 READ axis5 WRITE setAxis5 NOTIFY axis5Changed FINAL)
    Q_PROPERTY(AxisState axis81 READ axis81 WRITE setAxis81 NOTIFY axis81Changed FINAL)
    Q_PROPERTY(AxisState axis82 READ axis82 WRITE setAxis82 NOTIFY axis82Changed FINAL)
    Q_PROPERTY(double rockerX READ rockerX WRITE setRockerX NOTIFY rockerXChanged FINAL)
    Q_PROPERTY(double rockerY READ rockerY WRITE setRockerY NOTIFY rockerYChanged FINAL)

    // 控制台
    Q_PROPERTY(ButtonState button21 READ button21 WRITE setButton21 NOTIFY button21Changed FINAL)
    Q_PROPERTY(ButtonState button22 READ button22 WRITE setButton22 NOTIFY button22Changed FINAL)
    Q_PROPERTY(ButtonState button23 READ button23 WRITE setButton23 NOTIFY button23Changed FINAL)
    Q_PROPERTY(Switcher2State switcher21 READ switcher21 WRITE setSwitcher21 NOTIFY switcher21Changed FINAL)
    Q_PROPERTY(Switcher2State switcher22 READ switcher22 WRITE setSwitcher22 NOTIFY switcher22Changed FINAL)
    Q_PROPERTY(Switcher2State switcher23 READ switcher23 WRITE setSwitcher23 NOTIFY switcher23Changed FINAL)
    Q_PROPERTY(Switcher2State switcher24 READ switcher24 WRITE setSwitcher24 NOTIFY switcher24Changed FINAL)
    Q_PROPERTY(Switcher2State switcher25 READ switcher25 WRITE setSwitcher25 NOTIFY switcher25Changed FINAL)
    Q_PROPERTY(Switcher3State switcher31 READ switcher31 WRITE setSwitcher31 NOTIFY switcher31Changed FINAL)
    Q_PROPERTY(Switcher3State switcher32 READ switcher32 WRITE setSwitcher32 NOTIFY switcher32Changed FINAL)
    Q_PROPERTY(Switcher3State switcher33 READ switcher33 WRITE setSwitcher33 NOTIFY switcher33Changed FINAL)
    Q_PROPERTY(Switcher3State switcher34 READ switcher34 WRITE setSwitcher34 NOTIFY switcher34Changed FINAL)
    Q_PROPERTY(Switcher3State switcher35 READ switcher35 WRITE setSwitcher35 NOTIFY switcher35Changed FINAL)
    Q_PROPERTY(Switcher3State switcher36 READ switcher36 WRITE setSwitcher36 NOTIFY switcher36Changed FINAL)
    Q_PROPERTY(Switcher3State switcher37 READ switcher37 WRITE setSwitcher37 NOTIFY switcher37Changed FINAL)
    Q_PROPERTY(Switcher3State switcher38 READ switcher38 WRITE setSwitcher38 NOTIFY switcher38Changed FINAL)
    Q_PROPERTY(AxisState axis42 READ axis42 WRITE setAxis42 NOTIFY axis42Changed FINAL)
    Q_PROPERTY(AxisState axis8 READ axis8 WRITE setAxis8 NOTIFY axis8Changed FINAL)
    Q_PROPERTY(double slider READ slider WRITE setSlider NOTIFY sliderChanged FINAL)
    Q_PROPERTY(double axisSliderX READ axisSliderX WRITE setAxisSliderX NOTIFY axisSliderXChanged FINAL)
    Q_PROPERTY(double axisSliderY READ axisSliderY WRITE setAxisSliderY NOTIFY axisSliderYChanged FINAL)
    Q_PROPERTY(bool axisSliderPressed READ axisSliderPressed WRITE setAxisSliderPressed NOTIFY axisSliderPressedChanged FINAL)
    Q_PROPERTY(double pusher1 READ pusher1 WRITE setPusher1 NOTIFY pusher1Changed FINAL)
    Q_PROPERTY(double pusher2 READ pusher2 WRITE setPusher2 NOTIFY pusher2Changed FINAL)

public:
    enum AxisState {        // axis控件的状态
        Axis_RELEASE,
        Axis_UP,
        Axis_DOWN,
        Axis_LEFT,
        Axis_RIGHT,
        Axis_LEFT_UP,
        Axis_LEFT_DOWN,
        Axis_RIGHT_UP,
        Axis_RIGHT_DOWN,
        Axis_PRESSED
    };
    Q_ENUM(AxisState)

    enum ButtonState {      // button控件的状态
        Button_RELEASE,
        Button_PUSHED
    };
    Q_ENUM(ButtonState)

    enum TriggerState {     // trigger控件的状态
        Trigger_RELEASE,
        Trigger_PUSHED
    };
    Q_ENUM(TriggerState)

    enum Switcher2State {   // 两状态开关
        Switcher2_OFF,
        Switcher2_ON
    };
    Q_ENUM(Switcher2State)

    enum Switcher3State {   // 三状态开关
        Switcher3_UP,
        Switcher3_MID,
        Switcher3_DOWN
    };
    Q_ENUM(Switcher3State)

public:
    explicit JoystickReader(QObject *parent = nullptr);
    ~JoystickReader();

    Q_INVOKABLE void readJoystickData();

    ButtonState button1() const;
    void setButton1(ButtonState newButton1);

    ButtonState button2() const;
    void setButton2(ButtonState newButton2);

    ButtonState button3() const;
    void setButton3(ButtonState newButton3);

    TriggerState trigger1() const;
    void setTrigger1(TriggerState newTrigger1);

    TriggerState trigger2() const;
    void setTrigger2(TriggerState newTrigger2);

    AxisState axis4() const;
    void setAxis4(AxisState newAxis4);

    AxisState axis5() const;
    void setAxis5(AxisState newAxis5);

    AxisState axis81() const;
    void setAxis81(AxisState newAxis81);

    AxisState axis82() const;
    void setAxis82(AxisState newAxis82);

    double rockerX() const;
    void setRockerX(double newRockerX);

    double rockerY() const;
    void setRockerY(double newRockerY);

    ButtonState button21() const;
    void setButton21(ButtonState newButton21);

    ButtonState button22() const;
    void setButton22(ButtonState newButton22);

    ButtonState button23() const;
    void setButton23(ButtonState newButton23);

    Switcher2State switcher21() const;
    void setSwitcher21(Switcher2State newSwitcher21);

    Switcher2State switcher22() const;
    void setSwitcher22(Switcher2State newSwitcher22);

    Switcher2State switcher23() const;
    void setSwitcher23(Switcher2State newSwitcher23);

    Switcher2State switcher24() const;
    void setSwitcher24(Switcher2State newSwitcher24);

    Switcher2State switcher25() const;
    void setSwitcher25(Switcher2State newSwitcher25);

    Switcher3State switcher31() const;
    void setSwitcher31(Switcher3State newSwitcher31);

    Switcher3State switcher32() const;
    void setSwitcher32(Switcher3State newSwitcher32);

    Switcher3State switcher33() const;
    void setSwitcher33(Switcher3State newSwitcher33);

    Switcher3State switcher34() const;
    void setSwitcher34(Switcher3State newSwitcher34);

    Switcher3State switcher35() const;
    void setSwitcher35(Switcher3State newSwitcher35);

    Switcher3State switcher36() const;
    void setSwitcher36(Switcher3State newSwitcher36);

    Switcher3State switcher37() const;
    void setSwitcher37(Switcher3State newSwitcher37);

    Switcher3State switcher38() const;
    void setSwitcher38(Switcher3State newSwitcher38);

    AxisState axis8() const;
    void setAxis8(AxisState newAxis8);

    double axisSliderX() const;
    void setAxisSliderX(double newAxisSliderX);

    double axisSliderY() const;
    void setAxisSliderY(double newAxisSliderY);

    AxisState axis42() const;
    void setAxis42(AxisState newAxis42);

    bool axisSliderPressed() const;
    void setAxisSliderPressed(bool newAxisSliderPressed);

    double slider() const;
    void setSlider(double newSlider);

    double pusher1() const;
    void setPusher1(double newPusher1);

    double pusher2() const;
    void setPusher2(double newPusher2);

private:
    void parse1Buttons(unsigned char data[], int n);
    void parse1Triggers(unsigned char data[], int n);
    void parse1Axis4(unsigned char data[], int n);
    void parse1Axis5(unsigned char data[], int n);
    void parse1Axis81(unsigned char data[], int n);
    void parse1Axis82(unsigned char data[], int n);
    void parse1Rocker(unsigned char data[], int n);

    void parse2Buttons(unsigned char data[], int n);
    void parse2Switcher2s(unsigned char data[], int n);
    void parse2Switcher3s(unsigned char data[], int n);
    void parse2Axis4(unsigned char data[], int n);
    void parse2Axis8(unsigned char data[], int n);
    void parse2AxisSlider(unsigned char data[], int n);
    void parse2Slider(unsigned char data[], int n);
    void parse2Pushers(unsigned char data[], int n);

    void printRawData(unsigned char data[], int n, int base);

signals:
    void joystickDataReceived(QString data);

    void button1Changed();

    void button2Changed();

    void button3Changed();

    void trigger1Changed();

    void trigger2Changed();

    void axis4Changed();

    void axis5Changed();

    void axis81Changed();

    void axis82Changed();

    void rockerXChanged();

    void rockerYChanged();

    void button21Changed();

    void button22Changed();

    void button23Changed();

    void switcher21Changed();

    void switcher22Changed();

    void switcher23Changed();

    void switcher24Changed();

    void switcher25Changed();

    void switcher31Changed();

    void switcher32Changed();

    void switcher33Changed();

    void switcher34Changed();

    void switcher35Changed();

    void switcher36Changed();

    void switcher37Changed();

    void switcher38Changed();

    void axis8Changed();

    void axisSliderXChanged();

    void axisSliderYChanged();

    void axis42Changed();

    void axisSliderPressedChanged();

    void sliderChanged();

    void pusher1Changed();

    void pusher2Changed();

private:
    hid_device *joystick;       // 摇杆
    hid_device *joystick2;      // 控制台

    ButtonState m_button1;
    ButtonState m_button2;
    ButtonState m_button3;
    TriggerState m_trigger1;
    TriggerState m_trigger2;
    AxisState m_axis4;
    AxisState m_axis5;
    AxisState m_axis81;
    AxisState m_axis82;
    double m_rockerX;
    double m_rockerY;

    ButtonState m_button21;
    ButtonState m_button22;
    ButtonState m_button23;
    Switcher2State m_switcher21;
    Switcher2State m_switcher22;
    Switcher2State m_switcher23;
    Switcher2State m_switcher24;
    Switcher2State m_switcher25;
    Switcher3State m_switcher31;
    Switcher3State m_switcher32;
    Switcher3State m_switcher33;
    Switcher3State m_switcher34;
    Switcher3State m_switcher35;
    Switcher3State m_switcher36;
    Switcher3State m_switcher37;
    Switcher3State m_switcher38;
    AxisState m_axis42;
    AxisState m_axis8;
    double m_axisSliderX;
    double m_axisSliderY;
    bool m_axiSliderPressed;
    bool m_axisSliderPressed;
    double m_slider;
    double m_pusher1;
    double m_pusher2;
};

#endif // JOYSTICKREADER_H
